import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, cairo, GdkPixbuf
import random
import os

# 颜色定义
COLORS = [
    (1.0, 0.2, 0.2, 1.0),  # 红
    (0.2, 0.8, 0.2, 1.0),  # 绿
    (0.2, 0.2, 1.0, 1.0),  # 蓝
    (1.0, 1.0, 0.2, 1.0),  # 黄
    (1.0, 0.5, 0.0, 1.0),  # 橙
    (0.8, 0.2, 0.8, 1.0),  # 紫
    (0.2, 0.8, 0.8, 1.0),  # 青
    (0.9, 0.3, 0.6, 1.0)   # 粉
]

# 难度设置
DIFFICULTIES = {
    "easy": {
        "size": 12,
        "colors": 4,
        "moves": 21,
        "cell_size": 25
    },
    "medium": {
        "size": 18,
        "colors": 6,
        "moves": 31,
        "cell_size": 20
    },
    "hard": {
        "size": 24,
        "colors": 8,
        "moves": 42,
        "cell_size": 15
    }
}

# 以困难难度为标准计算固定窗口大小
HARD_SETTINGS = DIFFICULTIES["hard"]
FIXED_WIDTH = HARD_SETTINGS["size"] * HARD_SETTINGS["cell_size"] + 60  # 包含边距
FIXED_HEIGHT = HARD_SETTINGS["size"] * HARD_SETTINGS["cell_size"] + 160  # 包含菜单、标签等

# 游戏图标路径
ICON_PATH = "/opt/appimages/flood.png"
# 图标显示尺寸
ICON_SIZE = 64  # 64x64像素


class FloodGame:
    def __init__(self, difficulty):
        self.difficulty = difficulty
        self.reset()

    def reset(self):
        settings = DIFFICULTIES[self.difficulty]
        self.board = [[random.randint(0, settings["colors"] - 1) 
                      for _ in range(settings["size"])] 
                      for _ in range(settings["size"])]
        self.current_color = self.board[0][0]
        self.moves = 0
        self.game_over = False
        self.win = False

    def change_difficulty(self, difficulty):
        self.difficulty = difficulty
        self.reset()

    def make_move(self, new_color):
        settings = DIFFICULTIES[self.difficulty]
        if self.game_over or new_color == self.current_color:
            return
            
        self.moves += 1
        original_color = self.current_color
        self.current_color = new_color
        self._flood_fill(0, 0, original_color)
        
        # 检查游戏状态
        if self.moves >= settings["moves"]:
            self.game_over = True
            self.win = self.check_win()
        elif self.check_win():
            self.game_over = True
            self.win = True

    def _flood_fill(self, x, y, original_color):
        settings = DIFFICULTIES[self.difficulty]
        if x < 0 or x >= settings["size"] or y < 0 or y >= settings["size"]:
            return
        if self.board[x][y] != original_color:
            return
            
        self.board[x][y] = self.current_color
        self._flood_fill(x+1, y, original_color)
        self._flood_fill(x-1, y, original_color)
        self._flood_fill(x, y+1, original_color)
        self._flood_fill(x, y-1, original_color)

    def check_win(self):
        settings = DIFFICULTIES[self.difficulty]
        return all(self.board[i][j] == self.current_color 
                  for i in range(settings["size"]) 
                  for j in range(settings["size"]))


class FloodWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Flood Game")
        self.current_difficulty = "easy"
        
        # 尝试设置窗口图标
        self.set_window_icon_from_file()
        
        # 初始化游戏
        self.game = FloodGame(self.current_difficulty)
        
        # 设置固定窗口大小（以困难难度为标准）
        self.set_default_size(FIXED_WIDTH, FIXED_HEIGHT)
        self.set_resizable(False)  # 禁止用户调整窗口大小
        
        self.set_border_width(10)
        
        # 创建主容器
        self.main_vbox = Gtk.VBox(spacing=10)
        self.add(self.main_vbox)
        
        # 添加菜单
        self.create_menu()
        
        # 添加滚动窗口（低难度时内容会居中显示）
        self.scrolled_window = Gtk.ScrolledWindow()
        self.scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)  # 禁用滚动条
        self.main_vbox.pack_start(self.scrolled_window, True, True, 0)
        
        # 创建居中容器，使低难度棋盘在固定窗口中居中显示
        self.center_alignment = Gtk.Alignment(xalign=0.5, yalign=0.5)
        self.scrolled_window.add(self.center_alignment)
        
        # 棋盘网格
        self.board_grid = Gtk.Grid()
        self.board_grid.set_column_spacing(0)
        self.board_grid.set_row_spacing(0)
        self.center_alignment.add(self.board_grid)
        
        # 移动计数标签
        self.move_label = Gtk.Label()
        self.main_vbox.pack_start(self.move_label, False, False, 0)
        
        # 结果标签
        self.result_label = Gtk.Label()
        self.main_vbox.pack_start(self.result_label, False, False, 0)
        
        # 颜色选择区域
        self.color_hbox = Gtk.HBox(spacing=5)
        # 颜色选择按钮居中显示
        self.color_alignment = Gtk.Alignment(xalign=0.5, yalign=0.5)
        self.color_alignment.add(self.color_hbox)
        self.main_vbox.pack_start(self.color_alignment, False, False, 0)
        
        # 创建棋盘格子和颜色按钮
        self.create_game_elements()
        
        # 初始绘制
        self.draw_board()
        
        # 显示窗口
        self.show_all()

    def set_window_icon_from_file(self):
        """设置窗口图标"""
        if os.path.exists(ICON_PATH):
            try:
                # 加载图标并缩放到指定大小
                pixbuf = GdkPixbuf.Pixbuf.new_from_file(ICON_PATH)
                scaled_pixbuf = pixbuf.scale_simple(
                    ICON_SIZE, ICON_SIZE, 
                    GdkPixbuf.InterpType.BILINEAR  # 使用双线性插值保持图像质量
                )
                self.set_icon(scaled_pixbuf)
            except Exception as e:
                print(f"无法设置窗口图标: {e}")
        else:
            print(f"图标文件不存在: {ICON_PATH}")

    def create_menu(self):
        menubar = Gtk.MenuBar()
        
        # 文件菜单
        file_menu = Gtk.Menu()
        file_item = Gtk.MenuItem(label="文件")
        file_item.set_submenu(file_menu)
        
        # 新游戏
        new_game_item = Gtk.MenuItem(label="新游戏")
        new_game_item.connect("activate", self.on_new_game)
        file_menu.append(new_game_item)
        
        # 难度设置子菜单（已将"游戏设置"改为"难度设置"）
        difficulty_menu = Gtk.Menu()
        difficulty_item = Gtk.MenuItem(label="难度设置")
        difficulty_item.set_submenu(difficulty_menu)
        
        # 难度选项
        easy_item = Gtk.MenuItem(label="简单")
        easy_item.connect("activate", self.on_difficulty_change, "easy")
        medium_item = Gtk.MenuItem(label="中等")
        medium_item.connect("activate", self.on_difficulty_change, "medium")
        hard_item = Gtk.MenuItem(label="困难")
        hard_item.connect("activate", self.on_difficulty_change, "hard")
        
        difficulty_menu.append(easy_item)
        difficulty_menu.append(medium_item)
        difficulty_menu.append(hard_item)
        file_menu.append(difficulty_item)
        
        # 退出
        exit_item = Gtk.MenuItem(label="退出")
        exit_item.connect("activate", Gtk.main_quit)
        file_menu.append(exit_item)
        
        # 帮助菜单
        help_menu = Gtk.Menu()
        help_item = Gtk.MenuItem(label="帮助")
        help_item.set_submenu(help_menu)
        
        # 关于
        about_item = Gtk.MenuItem(label="关于")
        about_item.connect("activate", self.show_about)
        help_menu.append(about_item)
        
        menubar.append(file_item)
        menubar.append(help_item)
        self.main_vbox.pack_start(menubar, False, False, 0)

    def create_game_elements(self):
        """创建棋盘格子和颜色按钮"""
        # 清除现有元素
        for child in self.board_grid.get_children():
            self.board_grid.remove(child)
        for child in self.color_hbox.get_children():
            self.color_hbox.remove(child)
            
        settings = DIFFICULTIES[self.current_difficulty]
        
        # 创建棋盘格子
        self.board_cells = []
        for i in range(settings["size"]):
            row = []
            for j in range(settings["size"]):
                cell = Gtk.DrawingArea()
                cell.set_size_request(settings["cell_size"], settings["cell_size"])
                cell.connect("draw", self.draw_cell, i, j)
                self.board_grid.attach(cell, j, i, 1, 1)
                row.append(cell)
            self.board_cells.append(row)
        
        # 创建颜色选择按钮
        self.color_buttons = []
        for i in range(settings["colors"]):
            btn = Gtk.Button()
            btn.set_size_request(40, 40)
            da = Gtk.DrawingArea()
            da.set_size_request(40, 40)
            da.connect("draw", self.draw_color_button, i)
            btn.add(da)
            btn.connect("clicked", self.on_color_select, i)
            self.color_hbox.pack_start(btn, True, True, 5)
            self.color_buttons.append(btn)

    def draw_cell(self, widget, cr, row, col):
        """绘制棋盘格子，无分割线"""
        try:
            color_idx = self.game.board[row][col]
            color = COLORS[color_idx]
            
            # 绘制颜色
            cr.set_source_rgba(*color)
            cr.rectangle(0, 0, widget.get_allocated_width(), widget.get_allocated_height())
            cr.fill()
        except:
            pass
        return False

    def draw_color_button(self, widget, cr, color_idx):
        """绘制颜色按钮"""
        color = COLORS[color_idx]
        cr.set_source_rgba(*color)
        cr.rectangle(0, 0, widget.get_allocated_width(), widget.get_allocated_height())
        cr.fill()
        
        # 颜色按钮保留边框
        cr.set_source_rgba(0.5, 0.5, 0.5, 1.0)
        cr.set_line_width(1)
        cr.rectangle(0, 0, widget.get_allocated_width()-1, widget.get_allocated_height()-1)
        cr.stroke()
        return False

    def draw_board(self):
        """重绘整个棋盘"""
        settings = DIFFICULTIES[self.current_difficulty]
        
        # 更新移动计数
        self.move_label.set_text(f"移动次数: {self.game.moves}/{settings['moves']}")
        
        # 更新结果标签
        if self.game.game_over:
            if self.game.win:
                self.result_label.set_text("恭喜，你赢了！")
            else:
                self.result_label.set_text("游戏结束，尝试新游戏吧！")
            # 禁用颜色按钮
            for btn in self.color_buttons:
                btn.set_sensitive(False)
        else:
            self.result_label.set_text("")
            # 启用颜色按钮
            for btn in self.color_buttons:
                btn.set_sensitive(True)
        
        # 强制重绘所有棋盘格子
        for i in range(settings["size"]):
            for j in range(settings["size"]):
                self.board_cells[i][j].queue_draw()

    def on_color_select(self, widget, color_idx):
        # 执行移动
        self.game.make_move(color_idx)
        # 重绘棋盘
        self.draw_board()

    def on_new_game(self, widget):
        # 重置游戏状态
        self.game.reset()
        # 重绘棋盘
        self.draw_board()

    def on_difficulty_change(self, widget, difficulty):
        # 更改难度并重新创建游戏元素
        self.current_difficulty = difficulty
        self.game.change_difficulty(difficulty)
        self.create_game_elements()
        self.draw_board()
        # 刷新显示
        self.show_all()

    def show_about(self, widget):
        about_dialog = Gtk.AboutDialog()
        about_dialog.set_transient_for(self)
        about_dialog.set_program_name("Flood 游戏")
        about_dialog.set_version("1.0")
        about_dialog.set_copyright("© 2023 豆包")
        about_dialog.set_comments("一个有趣的Flood填充游戏")
        
        # 设置关于窗口的图标并缩放到64x64
        if os.path.exists(ICON_PATH):
            try:
                pixbuf = GdkPixbuf.Pixbuf.new_from_file(ICON_PATH)
                scaled_pixbuf = pixbuf.scale_simple(
                    ICON_SIZE, ICON_SIZE, 
                    GdkPixbuf.InterpType.BILINEAR  # 使用双线性插值保持图像质量
                )
                about_dialog.set_logo(scaled_pixbuf)
            except Exception as e:
                print(f"无法在关于窗口中设置图标: {e}")
        
        about_dialog.run()
        about_dialog.destroy()


if __name__ == "__main__":
    win = FloodWindow()
    win.connect("destroy", Gtk.main_quit)
    Gtk.main()
